package com.bwie.es.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bwie.common.domain.Car;
import com.bwie.common.domain.request.CarVO;
import com.bwie.common.result.PageResult;
import com.bwie.common.result.Result;
import com.bwie.common.utils.StringUtils;
import com.bwie.es.feign.EsFeign;
import com.bwie.es.service.Esservice;
import lombok.extern.log4j.Log4j2;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Log4j2
public class EsserviceImpl implements Esservice {
    @Autowired
    public EsFeign esFegin;
    @Autowired
    private StringRedisTemplate redisTemplatel;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public static final String INDEX_NAME="car";

    @Override
    public void batchAdd(List<Car> cars) {
        try {
            BulkRequest bulkRequest = new BulkRequest();
            cars.forEach(car -> {
                bulkRequest.add(
                        new IndexRequest(INDEX_NAME)
                                .id(car.getCarId()+"")
                                .source(JSONObject.toJSONString(car),XContentType.JSON)
                );
            });
            restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
        }catch (Exception ex){
            log.error("es错误{}",JSONObject.toJSON(cars),ex);
        }
//        try {
//            BulkRequest bulkRequest = new BulkRequest();
//            cars.forEach(car -> {
//                bulkRequest.add(
//                        new IndexRequest(INDEX_NAME)
//                                .id(car.getCarId()+"")
//                                .source(JSONObject.toJSONString(car), XContentType.JSON));
//            });
//            restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
//        }catch (Exception ex){
//            log.error("Es错误"+ JSONObject.toJSONString(cars),ex);
//        }
    }

    @Override
    public Result<PageResult<Car>> search(CarVO carVO) {
        long total =0;
        ArrayList<Car> car1 = new ArrayList<>();
        try {
//            SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

            SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

            if(StringUtils.isAnyBlank(carVO.getCarName())){
                boolQueryBuilder.must(QueryBuilders.matchQuery("carName",carVO.getCarName()));
            }
            if(carVO.getStart()!=null){
                boolQueryBuilder.must(QueryBuilders.rangeQuery("carTime").gte(carVO.getStart().getTime()));
            }
            if(carVO.getEnd()!=null){
                boolQueryBuilder.must(QueryBuilders.rangeQuery("carTime").lte(carVO.getEnd().getTime()));
            }



//            if(StringUtils.isNotBlank(carVO.getCarName())){
//                boolQueryBuilder.must(QueryBuilders.matchQuery("carName",carVO.getCarName()));
//            }
//            if(carVO.getStart()!=null){
//                boolQueryBuilder.must(QueryBuilders.rangeQuery("carTime").gte(carVO.getStart().getTime()));
//            }
//            if(carVO.getEnd()!=null){
//                boolQueryBuilder.must(QueryBuilders.rangeQuery("carTime").lte(carVO.getEnd().getTime()));
//            }
            searchSourceBuilder.query(boolQueryBuilder);
            searchSourceBuilder.from((carVO.getPageNum()-1)*carVO.getPageSize());
            searchSourceBuilder.size(carVO.getPageSize());
            searchSourceBuilder.sort("carTime", SortOrder.DESC);
//            searchSourceBuilder.highlighter(
//                    new HighlightBuilder()
//                            .field("carName")
//                            .preTags("<font style=\"color:red;\">")
//                            .postTags("</font>")
//            );
            searchSourceBuilder.highlighter(
                    new HighlightBuilder()
                            .field("carName")
                            .preTags("<font style=\"color:red;\">")
                            .postTags("</font>")
            );
            searchRequest.source(searchSourceBuilder);

            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits hits = searchResponse.getHits();
            total=hits.getTotalHits().value;
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit searchHit : searchHits) {
                String sourceAsString = searchHit.getSourceAsString();
                Car car = JSONObject.parseObject(sourceAsString, Car.class);
                Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                if(highlightFields!=null){
                    HighlightField highlightField = highlightFields.get("carName");
                    if(highlightField!=null){
                        Text[] fragments = highlightField.fragments();
                        String str ="";
                        for (Text fragment : fragments) {
                            str+=fragment;
                            car.setCarName(str);
                        }
                    }
                }
                car1.add(car);
            }

//            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//            SearchHits hits = searchResponse.getHits();
//            total=hits.getTotalHits().value;
//            SearchHit[] searchHits = hits.getHits();
//            for (SearchHit searchHit : searchHits) {
//                String sourceAsString = searchHit.getSourceAsString();
//                Car car = JSONObject.parseObject(sourceAsString, Car.class);
//                Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
//                if(highlightFields!=null){
//                    HighlightField highlightField = highlightFields.get("carName");
//                    if(highlightField!=null){
//                        Text[] fragments = highlightField.fragments();
//                        String str ="";
//                        for (Text fragment : fragments) {
//                            str+=fragment;
//                            car.setCarName(str);
//                        }
////                        StringBuilder sb = new StringBuilder();
////                        for (Text fragment : fragments) {
////                            sb.append(fragment);
////                        }
////                        car.setCarName(sb.toString());
//                    }
//                }
////                car.setCarId(Integer.valueOf(searchHit.getId()));
//                car1.add(car);
//            }


        }catch (Exception ex){
            throw new RuntimeException(ex);
        }
        return PageResult.toResult(total,car1);
    }
}
